#define _CRT_SECURE_NO_WARNINGS

#include"convert_comment.h"

int status = COMMONSTATUS;



void common_status(FILE* ifp, FILE* ofp)
{
	int c = fgetc(ifp);

	if ('/' == c)
	{
		c = fgetc(ifp);

		if ('*' == c)//表示是C语言风格注释
		{
			fputc('/', ofp);
			fputc('/', ofp);
			status = CSTATUS;

		}
		else if ('/' == c)//表示是C++风格注释
		{
			fputc('/', ofp);
			fputc('/', ofp);
			status = CPPSTATUS;

		}
		else if (EOF == c)//结束状态
		{
			status = EOFSTATUS;

		}
		else//普通的无注释代码
		{
			fputc(c, ofp);
			ungetc(c, ifp);
			status = COMMONSTATUS;
		}
	}

	else if (EOF == c)
	{
		status = EOFSTATUS;
		ungetc(c, ifp);
	}


	else//是换行，或者无注释的代码
	{
		fputc(c, ofp);
		status = COMMONSTATUS;
	}
}

void c_status(FILE* ifp, FILE* ofp)
{
	int c = fgetc(ifp);


	if ('*' == c)
	{
		c = fgetc(ifp);

		if ('/' == c)
		{
			fputc('\n', ofp);/*若C语言风格注释末尾紧接代码，此处必修保留，不能注释掉。
							 虽然输出每一小段都会多一行，但保证了C语言注释后面紧跟内容的话，不会被CPP注释风格注释掉。*/
			status = COMMONSTATUS;

		}
		else
		{
			/*语句进行到这里，表示这不是C风格注释的结束，只是简单的'*'需要被存入目标文件。
			经过两次fgetc语句，此时输入流的‘*’已经被读取，而且'*'的下一个字符也已被读入。主动将'*'符号存入。*/
			fputc('*', ofp);
			//将第二次fgetc语句读入的字符返回输入流，让下次函数再判断是否是C注释结束
			ungetc(c, ifp);
			status = CSTATUS;
		}
	}

	else if (EOF == c)
	{
		status = EOFSTATUS;
	}

	else if ('\n' == c)//多行注释，主动为下一行注释添加//，表示转换成CPP注释
	{
		fputc(c, ofp);
		fputc('/', ofp);
		fputc('/', ofp);
		status = CSTATUS;
	}

	else
	{
		fputc(c, ofp);
		status = CSTATUS;
	}
}

void cpp_status(FILE* ifp, FILE* ofp)
{
	int c = fgetc(ifp);

	if (EOF == c)
	{
		status = EOFSTATUS;
	}

	else if ('\n' == c)
	{
		fputc('\n', ofp);
		status = COMMONSTATUS;
	}
	else
	{
		fputc(c, ofp);
		status = CPPSTATUS;
	}
}

static void conver_work(FILE *ifp, FILE *ofp)
{

	while (status != EOFSTATUS)
	{
		switch (status)
		{
		case COMMONSTATUS:
			common_status(ifp, ofp);
			break;
		case CPPSTATUS:
			cpp_status(ifp, ofp);
			break;
		case CSTATUS:
			c_status(ifp, ofp);
			break;
		default:
			break;
		}
	}

}

void convert_commment()
{
	FILE *ifp = fopen(INPUTFILE, "r");
	FILE *ofp = fopen(OUTPUTFILE, "w");

	if (ifp == NULL || ofp == NULL)
	{
		perror("Open fail");//使用perror函数提示原因
		return;
	}

	conver_work(ifp, ofp);
	printf("Annotation has been convert, please see file.\n");

	fclose(ifp);
	fclose(ofp);
}
